<?php

/**
 * PHP versions 4 and 5
 * MagicPHP
 * Licensed under The Open Group Test Suite License
 * Redistributions of files must retain the above copyright notice.
 * @copyright     Copyright 2011
 * @link
 * @package       Model
 * @since         MaginPHP 1.0
 * @license
 */
?>

<?php

/**
 * @desc This function is used for basic insert update and delete
 * functionality
 * @author aNKIT kHAMBHATA
 */
class Magic_CURD_Model {

    /**
     * @desc:This is the instance variable of self
     * @var type 
     */
    private static $_instance;

    /**
     * @desc : Contain name of table 
     * @var type 
     */
    private $table;

    /**
     * @desc : This variable show image status
     */
    private $image_status;

    /**
     * @desc : array of field
     * @var type 
     */
    private $f;

    /**
     * @desc : Array of data
     * @var type 
     */
    private $d;

    /**
     * @desc : This variable show image field
     */
    private $image_field;

    /**
     * @desc : This variable show image value
     */
    private $image_value;

    /**
     * @desc : This variable capture value of field
     */
    private $data;

    /**
     * @desc : This variable capture array of field
     */
    private $fields;

    /**
     * @desc : This parameter contain query string 
     */
    private $query;

    /**
     * @desc : Left Join Pattern  
     */
    private $l_j_patter = '/\bleft join\b/i';

    /**
     * @desc: Right Join Pattern
     * @var type 
     */
    private $r_j_patter = '/\bright join\b/i';

    /**
     * Join pattern
     * @var type 
     */
    private $j_patter = '/\bjoin\b/i';
    /**
     * @desc : mysql result variable
     * @var type 
     */
    private $res ;
    /**
     * @desc : varibale is used to find 
     * particular pattern from the string 
     * if exist and replace with particular
     * pattern 
     */
    private $l_findpatteren = '/\bLEFT JOIN\b/';
    private $l_replacepattern = 'left join';
    private $r_findpatteren = '/\bRIGHT JOIN\b/';
    private $r_replacepattern = 'right join';
    private $s_findpatteren = '/\bJOIN\b/';
    private $s_replacepattern = 'join';

    /**
     * @desc : Define where condition 
     * @var type 
     */
    private $whereCondition;

    /**
     * @author : aNKIT kHAMBHATA
     * @desc: This function is used to give instance of class 
     */
    public static function callMethod() {
        self::$_instance = new self;
        return self::$_instance;
    }

    /**
     * @author: aNKIT kHAMBHATA
     * @param: $table : name of table
     * @param: $field : array of field
     * @param: $data : array of data
     * @param: $condition : where condition for update query
     * @param: $case : type of 	query
     */
    private static function queryGenerator($table, $field, $data, $condition, $case, $join = NULL) {
        $sql = '';
        switch ($case) {
            case INSERSQL:
                $sql = INSERT_IN_TO . " $table (" . implode(',', $field) . ") " . VLU . " (" . implode(',', $data) . ")";
                break;
            case UPDATESQL:
                $sql = UPDATE . " $table " . UPDATE_SET . " " . implode(',', $data) . " where $condition";
                break;
            case ROWCOUNTER :
                $sql = SLCT . " " . C_START . " as num " . FRM . " $table where $condition";
                break;
            case DELETESQL :
                $sql = DLCT . " " . FRM . " " . $table . " where $condition";
                break;
            case FETCHTABLEFIELD :
                $sql = "SHOW COLUMNS " . FRM . $table;
                break;
            case FETCHSQL :
                $sql = SLCT . " " . ASTRIKE . " " . FRM . " " . $table . " " . WHR . " " . $condition;
                break;
            case FETCHWITHMULTIPLE_TABLE :
                $sql = SLCT . " " . $field . " " . FRM . " " . $table . " " . WHR . " " . $condition;
                break;
            case LEFT_JOIN :
                $sql = SLCT . " " . @implode(",", $field) . " " . FRM . " " . $table . " " . $join . " " . WHR . " " . $condition;
                break;
        }
        return $sql;
    }

    /**
     * @author : aNKIT kHAMBHATA
     * @desc: Fileter the data from sql injunction
     * @param $data: value of data
     */
    private static function dataFilter($data) {
//        return mysql_real_escape_string(trim($data));
        return (trim($data));
    }

    /**
     * @desc : Use for run the query 
     * @param type $sql : database query 
     * @return boolean 
     */
    private function runSql($sql) {
        $this->res = @mysql_query($sql);
        try {
            if ($this->res) {
                return $this->res;
            } else {
               return FALSE;
            }
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * @desc : Use to define Table 
     * @param type $tb : name of table
     * @return \Magic_Orm_Model 
     */
    public function defineTable($tb) {
        $this->table = $tb;
        return $this;
    }

    /**
     * @desc : Use to define table fields 
     * @param type $fie : array or table field 
     * @return \Magic_Orm_Model 
     */
    public function defineField($fie) {
        if (is_array($fie))
            $this->f = $fie;
        return $this;
    }

    /**
     * @desc : Use to define table data 
     * @param type $fd
     * @return \Magic_Orm_Model 
     */
    public function defineFieldData($fd) {
        if (isset($this->f) && is_array($fd)) {
            $dataArray = array_combine($this->f, $fd);
        }
        $this->d = $dataArray;
        return $this;
    }

    /**
     * @desc : Use to set Image Status
     * @param type $status : true/ false 
     * @return \Magic_Orm_Model 
     */
    public function imageStatus($status = false) {
        $status == true ? $this->image_status = 1 : $this->image_status = 0;
        return $this;
    }

    /**
     * @desc : Use to define Image field 
     * @param type $if : name of the image field 
     * @return \Magic_Orm_Model 
     */
    public function imageField($if) {
        $this->image_field = $if;
        return $this;
    }

    /**
     * @desc : Use to define Image Field Value
     * @param type $fieldValue : value of the Image Field 
     * @return \Magic_Orm_Model 
     */
    public function imageValue($fieldValue) {
        $this->image_value = $fieldValue;
        return $this;
    }

    /**
     * @desc : Private Function Use to Bind the Parameters  
     * For Insert Operation into Database
     */
    private function bindParameter() {
       
        if ($this->image_status == '1') {
            $this->data[] = "'" . $this->image_value . "'";
            $this->fields[] = ($this->image_field);
        }
        for ($i = 0; $i < count($this->f); $i++) {
            if (is_array($this->d[$this->f[$i]])) {
                $data_arr = implode(',', $this->d[$this->f[$i]]);
            } else {
                $data_arr = $this->d[$this->f[$i]];
            }
            $this->data[] = "'" . self ::dataFilter($data_arr) . "'";
            $this->fields[] = $this->f[$i];
        }
    }

    /**
     * @desc : Use to Bind parameter for 
     * Update Operation into Database 
     * @return string 
     */
    private function bindParameterForUpdate() {
        $str = '';
        if ($this->image_status == '1') {
            $this->data[] = "'" . $this->image_value . "'";
            $this->fields[] = ($this->image_field);
        }
        for ($i = 0; $i < count($this->f); $i++) {
            if (is_array($this->d[$this->f[$i]])) {
                if (sizeof($this->d[$this->f[$i]]) > 1) {
                    $data_arr = implode(',', $this->d[$this->f[$i]]);
                } else {
                    $data_arr = $this->d[$this->f[$i]];
                    $data_arr = $data_arr[0];
                }
            } else {
                if ($this->d[$this->f[$i]] == "") {
                    $data_arr = "";
                } else {
                    $format_string = (string) $this->d[$this->f[$i]];
                    $data_arr = $format_string;
                }
            }
            $parameters[] = $this->f[$i] . "=" . "'" . self :: DataFilter($data_arr) . "'";
        }
        return $parameters;
    }

    /**
     * @desc : Use to Insert Operation 
     * into Database 
     * @return \Magic_Orm_Model 
     */
    public function insert() {
         
        $this->bindParameter();
        $this->query = self ::queryGenerator($this->table, $this->fields, $this->data, "", INSERSQL);
        return $this;
    }

    /**
     * @desc : Define Where Condition for 
     * Database Query language
     * @param type $con : variable of query 
     * @return \Magic_Orm_Model 
     */
    public function where($con) {
        $this->whereCondition = $con;
        return $this;
    }

    /**
     * @desc : Use For Update Operation 
     * @return \Magic_Orm_Model 
     */
    public function update() {
        $this->query = self :: queryGenerator($this->table, '', $this->bindParameterForUpdate(), $this->whereCondition, UPDATESQL);
        return $this;
    }

    /**
     * @desc : Use For select Operation
     * @return \Magic_Orm_Model 
     */
    public function selectall() {
        $this->query = self :: queryGenerator($this->table, '', '', $this->whereCondition, FETCHSQL);
        return $this;
    }

    /**
     * @desc : Use For select Field 
     * For Muliple table form the Database Operation 
     * @param type $fld : array of the Filed 
     * @return \Magic_Orm_Model 
     */
    public function selectField($fld = array()) {
        if (is_array($fld)) {
            $fCount = count($fld);
            $sField = implode(",", $fld);
        }
        if ($fCount > 0) {
            $this->query = self ::queryGenerator($this->table, $sField, '', $this->whereCondition, FETCHWITHMULTIPLE_TABLE);
        }
        return $this;
    }

    /**
     * @desc : Use To Delete Operation 
     * @return \Magic_Orm_Model 
     */
    public function delete() {
        $this->query = self ::queryGenerator($this->table, '', '', $this->whereCondition, DELETESQL);
        return $this;
    }
    /**
     * @desc : Function is used to Define Left Join
     * @param type $lf 
     */
    public function leftjoin($lf) {
        if ($this->matchPatteren($this->l_j_patter, $this->l_findpatteren, $this->l_replacepattern, $lf)) {
            $this->query = self :: queryGenerator($this->table, $this->f, '', $this->whereCondition, LEFT_JOIN, $lf);
            return $this;
        } else {
            echo new ErrorException(LEFT_JOIN_ERROR);
        }
    }

    /**
     * @desc : Function is use to define right join
     * @param type $lf
     * @return \Magic_Orm_Model 
     */
    public function rightjoin($lf) {
        if ($this->matchPatteren($this->r_j_patter, $this->r_findpatteren, $this->r_replacepattern, $lf)) {
            $this->query = self :: queryGenerator($this->table, $this->f, '', $this->whereCondition, LEFT_JOIN, $lf);
            return $this;
        } else {
            echo new ErrorException(RIGHT_JOIN_ERROR);
        }
    }

    /**
     * @desc : Function is used to Define  Join
     * @param type $lf 
     */
    public function join($lf) {
        if ($this->matchPatteren($this->j_patter, $this->s_findpatteren, $this->s_replacepattern, $lf)) {
            $this->query = self :: queryGenerator($this->table, $this->f, '', $this->whereCondition, LEFT_JOIN, $lf);
            return $this;
        } else {
            echo new ErrorException(JOIN_ERROR);
        }
    }

    /**
     * @desc : Use for count of numbers of rows 
     * from the database table 
     * @return \Magic_Orm_Model 
     */
    public function rowcount() {
        $this->query = self :: queryGenerator($this->table, '', '', $this->whereCondition, ROWCOUNTER);
        return $this;
    }
   
    /**
     * @desc : Command is use to execute the sql query 
     * @return boolean 
     */
    public function execute($flag = false) {
        if($flag) {
             $this->res = $this->runSql($this->query);
             return $this;
        } else {
            $this->res = $this->runSql($this->query);
            if ($this->res) {
                return $this->res;
            } else {
                return false;
            }
        }
    }
    /**
     * @desc : User to return database array 
     */
    public function magicFetchAssoc(){
        if($this->res) {
            return @mysql_fetch_assoc($this->res);
        } else {
            return false; 
        }
    }

    /**
     * @desc : This function is used to run
     * coustom built query 
     * @param type $qy : query string 
     * @return \Magic_Orm_Model 
     */
    public function coustomBuiltQuery($qy) {
        $this->query = $qy;
        return $this;
    }

    /**
     * @desc : This command is use  to 
     * debut the Query  
     */
    public function debug($return = false) {
        if($return == true) {
            if (!empty($this->query)) {
                echo $this->query;
            } else {
                echo QUERY_NOT_SET;
            }
        } else {
            if (!empty($this->query)) {
                return  $this->query;
            } else {
                return QUERY_NOT_SET;
            }
        }
    }
    /**
     * @desc : Use to free mysql result set
     * Replace the mysql_free_result functions  
     */
    public function magicFreeResult(){
        if(isset($this->query)) {
            @mysql_free_result($this->query);
        }
    }
    /**
     * @desc : Function is used to match pattern from the string 
     * @param type $matchpatteren : pattern that will use to match from the string 
     * @param type $findpatteren : find particular pattern from the string 
     * @param type $replacepattern : replace the particular find pattern
     * @param type $string : the string in which pattern is find ,replace and match
     * @return boolean 
     */
    private function matchPatteren($matchpatteren, $findpatteren, $replacepattern, $string) {
        preg_replace($findpatteren, $replacepattern, $string);
        if (preg_match($matchpatteren, $string)) {
            return true;
        } else {
            return false;
        }
    }

}
// End Of Model 
?>